package com.atguigu.gmall.seckill.core;

import com.atguigu.gmall.common.constans.RedisConstant;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.common.util.JsonUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.seckill.firstcache.SeckillFirstcache;
import com.atguigu.gmall.seckill.service.SeckillGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author A
 * @version 1.0
 * @description: TODO
 * @date 2025/9/18 3:26
 */
@Slf4j
@Component
public class SeckillTask {
    @Autowired
    private SeckillGoodsService seckillGoodsService;
    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    RedissonClient redissonClient;
    @Autowired
    SeckillFirstcache seckillFirstcache;
    //上架第二天的秒杀商品
    //@Scheduled(cron = "0 0 23 * * ?") //每天22点执行
    @Scheduled(cron = "0 */5 * * * ?") //每5分钟执行
    public void upSecKillSecondDay() {
        //准备第二天的秒杀商品
//        LocalDateTime localDateTime = LocalDateTime.now().plusDays(1);
//        String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String format = DateUtil.formatDate(new Date());
        List<SeckillGoods> seckillGoods = prepareSecKillGoodsDescDate(format);

        //上架秒杀商品
        upSecKillGoods(seckillGoods, format);
        //给缓存中商品设置信号量,供秒杀用户抢购

        prepareRedisSemaphore(seckillGoods,format);

        //给一级缓存中缓存秒杀商品
        seckillFirstcache.upSeckillCache(seckillGoods);
    }
    //准备缓存中商品的信号量
    private void prepareRedisSemaphore(List<SeckillGoods> seckillGoods, String format) {
        seckillGoods
                .forEach(seckillGood -> {
                    String key=RedisConstant.SECKILL_GOODS_SEMAPHORE_PREFIX+format+":"+seckillGood.getSkuId();
                    RSemaphore semaphore = redissonClient.getSemaphore(key);
                    //初始化信号量
                    semaphore.trySetPermits(seckillGood.getStockCount());

                });
            log.info("初始化{}的秒杀商品信号量",format);
    }

    //上架秒杀商品
    private void upSecKillGoods(List<SeckillGoods> seckillGoods, String format) {

        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(RedisConstant.SECKILL_GOODS_LIST_PREFIX + format);
        seckillGoods.forEach(item->{
            operations.put(item.getSkuId().toString(), JsonUtil.toStr(item));
        });
        log.info("上架{}的秒杀商品",format);
    }

    //准备特定日期的秒杀商品
    private List<SeckillGoods> prepareSecKillGoodsDescDate(String date) {
        log.info("准备{}的秒杀商品",date);
       return seckillGoodsService.seckillListDescDate(date);

    }


}
